package hku.cs.lunuo.rank;

import java.util.ArrayList;
import java.util.List;

/*CBI for any predicate should be rank its true and false branches.
 * So we use "block 1" present "predicate in block 1 true"
 * and "block 1 > -1" present "reverse predicate in block 1 false"
 * */

public class Cbi implements RankAlgorithm{

	@Override
	public List<Result> compute(Statistic s) {
		PredStatistic statistic = (PredStatistic) s;
		List<Result> result = new ArrayList<Result>();
		int numP = statistic.getTotalFls();
		for (int i = 0, j = statistic.getSize(); i < j; i++) {
			HelpPredStatistic hps = statistic.getSOfClass(i);

			String klassName = hps.getKlassName();

			for (String methodName : hps.getMethods()) {
				ComPredStatistic cps = hps.getCPSOfMethod(methodName);
				for (String blk : cps.getBlk()) {
					int fP = cps.getFlsTimesOfP(blk);
					int sP = cps.getTruTimesOfP(blk);
					
					int zz = Integer.parseInt(blk.split(">")[0]);
					
					int fPO = cps.getFlsTimesOfPO(zz);
					int sPO = cps.getTruTimesOfPO(zz);
	
					float failureP = (float)fP / (fP + sP);
					float contextP = (float)fPO / (fPO + sPO);
					float increaseP = failureP - contextP;
//					if(isValide(increaseP)) {
//						System.out.println("increase is valide");
						
						double importantP;
						if(fP ==1)
							importantP = 0;
						else
							importantP = 2 / (1 / increaseP + Math.log(numP)
							/ Math.log(fP));

						result.add(new PredResult((float) importantP, klassName, methodName, blk));
				
//					}
				}
			}

		}
		return result;
	}

	
	public boolean isValide(float p) {
		if(p<0.000001)
			return false;
		else
			return true;
	}
	
	@Override
	public boolean isPredRankAlg() {
		return true;
	}


	@Override
	public boolean isStmtRankAlg() {
		return false;
	}


	@Override
	public String getName() {
		return RankAlgorithm.CBI;
	}
}
